!pr0
!lm12
!rm75
!tm3
Converting ToolKit Source to S-C...........Bob Sander-Cederlof

I had the source code for FIG-FORTH on the Apple, entered by some members of the Dallas Apple Corps.  For some reason they decided to use the DOS ToolKit Assembler when they typed in all those lines.  Naturally, I had a strong desire to convert the source files to the format of my S-C Macro Assembler.

The first step, and one of the easiest in this case, is to figure out how to read the ToolKit source files into S-C.  ToolKit source files are standard DOS text files (type "T").  There are no line numbers.  S-C allows such files to be read in by typing the following commands:

!lm+5
NEW
AUTO
<<<<<EXEC filename   (where "<" stands for backspace)
<<<<<MANUAL
!lm-5

"NEW" makes sure there are no lingering program lines from a previous load.  "AUTO" starts generating automatic line numbers.  The first line number generated will be 1000.  Five backspaces will back up the cursor to the beginning of the input line, so the EXEC command can be typed.  As the file is EXECing, each line will be read in with a prefixed line number.  After the whole file has been read, five backspaces allow you to type the "MANUAL" command, thereby turning off the AUTO mode.

At this point you can LIST the program in memory and see what a ToolKit file looks like when you are using the S-C editor.  You could use the EDIT and REPLACE commands to make all the necessary changes, and SAVE the converted program on a new file.

I was able to automate much of the conversion process, using an EXEC file of REPLACE commands.  Several of you readers, including Graeme Scott of DFX fame, have sent me similar EXEC files for converting LISA source code.

Before I lay out the whole file, lets look at a simple case.  The people who typed in the ToolKit source decided to separate individual sections of code with "SKP 1" lines.  This causes a blank line on the assembly listing.  S-C does not have an equivalent directive, but then again I personally don't like blank lines on my listings.  (They always make me think my printer is broken!)  Anyway, the command REP / SKP 1/*/A replaces all of the skips with empty comment lines.  If you don't even want to see the asterisk on the line, use REP / SKP 1/ /A.

Notice that there is one space before "SKP" in the command above.  ToolKit uses space as a tab character, and so the source file does not have nice neat columns for each field.  If you list it with a regular text editor, the opcode field winds around like a snake; it always starting one space after the label, or in column 2 if there is no label.  S-C uses control-I for a tab character, because control-I is the ASCII tab character.  More on this later.

There were also a number of " SKP 2" lines.  I decided to turn these into "*--------" lines, to indicated a greater separation than a mere empty comment line would.

ToolKit uses the semi-colon in column 1 to indicate a comment line; S-C uses an asterisk.  ToolKit also uses a semi-colon to begin a comment field on a source line; S-C does not require any such character.  The following two replace commands will make the necessary changes:

!lm+5
REP / ;/  /A
REP /;/*/A
!lm-5

The commands have to be in that order, or else you end up with an asterisk starting comment fields when they aren't necessary.  Two lines had ";" in as ASCII literal constant.  I had to hand-re-correct them later.

The most important changes are the directives.  The files I was converting needed the following changes:

!lm+5
REP / EQU / .EQ /A
REP / DW / .DA /A
REP / ORG / .OR /A
REP / DS / .BS /A
REP / DCI / .AT /A
REP / DFB / .DA #/
REP / ASC / .AS /
!lm-5

Immediate address mode also presented a problem.  ToolKit uses the form "LDA #<SSS" to indicate the high byte, and "LDA #>SSS" to indicate the low byte.  S-C uses "LDA /SSS" for the high byte, and "LDA #SSS" for the low byte.  I fixed them with:

!lm+5
REP " <#" /"A
REP " >#" #"A
!lm-5

Now about those snaky columns....  I wanted to somehow put a tab before each opcode field, and before each comment field.  I thought, "Why not just use the replace command to put in a control-I?":

!lm+5
REP / EQU /^I.EQ /A    (where ^I means I typed control-I)
et cetera
!lm-5

My first problem was that typing controll-I when entering the REPLACE command made a tab.  I overcame that by typing the sequence "control-O control-I".  Control-O makes the next character become part of the input line regardless of its normal meaning.  That worked, but....

My second problem was that getting a control-I into the source program did not make it a tab.  Somehow the control-I had to be "executed".  So I wrote the converted program on a text file, this time with line numbers, and then EXECed it back in.

!lm+5
TEXT# filename
EXEC filename
!lm-5

That "executed" the control-I's, and I had tabs.  But....

My third problem was that I wanted to save all the REPLACE commands as an EXEC file, so that I did not have to manually retype them for every file to be converted.  When I EXECed the REPLACE command file, the control-I's were executed immediately!  I had to change my replace commands to include both a control-O and a control-I, so that the control-I in the REPLACE command would be read in from the EXEC file but not executed until it was later EXECed from the temporary source text file.

Still with me?  If not, keep reading anyway, because I will show you what I mean.

Using S-C, I entered the following "program":
!np
In the listing above, I have used "^O" to mean "control-O"; "^I" to mean "control-I"; and "^[" to mean "ESCAPE key".  In order to get "control-O control-I" in a line, I had to type "control-O control-O control-O control-I".

Lines 1000-1030, 1080,1130, 1170,1690, and 1720 begin with a quotation mark.  These are comment lines to the S-C input routine; they print on the screen when they are read from the EXEC file, but are otherwise ignored.

I saved the file as is using "SAVE TOOLKIT CONVERTER", in case I might want to modify it again.  And I did, again and again and again.  Then I wrote it on a text file without line numbers using "TEXT TKC".

Here is the sequence of steps I went through for each source file:

!lm+5
NEW
AUTO
1000 *    filename
<<<<<EXEC filename,D2   (where "<" means "backspace")
<<<<<MAN
EXEC TKC,D1
EXEC F
LIST 1000               (to see what filename to use)
SAVE filename
!lm-5

There are three EXEC commands above; the first reads on the ToolKit source file; the second executes all the REPLACE commands, and writes the resulting source on a temporary text file named "F"; the third reads in that temporary text file to "execute" the control-I tabs and the "ESC-L" lines.

After all the files were converted, I built a little assembly control file like this:

!lm+5
1000           .IN FILE1
1010           .IN FILE2
  et cetera
!lm-5

I also added a ".TF" directive after the ".OR" line, to put the assembled code on a DOS binary file.

The first assembly did not go smoothly, because of lines containing "ROR A".  In the four shift instructions, ToolKit requires the symbol "A" to signify Accumulator mode.  S-C uses a blank operand field to signify Accumulator mode, and thinks "ROR A" means to shift the memory location labeled "A".

Once I was able to assemble with no errors, I compared the object code produced with that produced by ToolKit.  They did not match!  There were two lines in the ToolKit source causing the problem:

!lm+5
         DW LIT,$FFFF
 L1495   DFB  $C1,$DB
!lm-5
!np
The "DW" directive in ToolKit does not recognize multiple items separated by commas; therefore the ",$FFFF" was ignored.  The following line in the source was "DW $FFFF".  The S-C form ".DA LIT,$FFFF" does assemble both items, so the $FFFF constant was duplicated.

The "DFB" directive in ToolKit recognizes multiple items.  The conversion I did rendered the line into "L1495  .DA #$C1,$DB", so the $DB item became a 16-bit value.  I changed the line to "L1495  .DA #$C1,#$DB" and all was well.

If you have a large Toolkit source to convert, chances are that you will find one or two more things to change that are not included above.  Let me know what you come up with.

As I mentioned earlier, the same general techniques work when you have a LISA file to convert.  If you can get the source code on a text file, with all tokens expanded, then you can read it into S-C and begin converting.  If you want a challenging assignment, how about writing a program which will read LISA type-B source files and convert them to S-C type-I source files, all automatically!
